package com.zhang.comm.utils;

import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author zsj
 * @description
 * @createDate 2025/11/14 10:13
 * @Entity com.zhang.comm.utils.entity.
 */
@Slf4j
public class FileValidationUtil {

    private FileValidationUtil() {}

    private final static String IMAGE_TYPE = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";

    /**
     * 验证文件头，判断真实文件类型
     */
    public static boolean validateFileHeader(MultipartFile file) {
        try (InputStream is = file.getInputStream()) {
            // 读取文件前10个字节（覆盖大部分类型的签名长度）
            byte[] header = new byte[10];
            int read = is.read(header);
            if (read < 1) {
                log.warn("文件内容为空");
                return false;
            }
            String hexHeader = bytesToHex(header);
            String extName = FileUtil.extName(file.getOriginalFilename()).toLowerCase();

            // 根据后缀名匹配对应的文件头签名（避免不同类型签名冲突）
            switch (extName) {
                case "bmp":
                case "dib":
                    return hexHeader.startsWith("424D"); // BM
                case "gif":
                    return hexHeader.startsWith("47494638"); // GIF8
                case "jpg":
                case "jpeg":
                    return hexHeader.startsWith("FFD8FF"); // JPEG起始
                case "png":
                    return hexHeader.startsWith("89504E47"); // PNG
                case "tif":
                    return hexHeader.startsWith("49492A00") || hexHeader.startsWith("4D4D002A"); // TIFF两种签名
                case "wmf":
                    return hexHeader.startsWith("D7CDC69A"); // WMF
                case "eps":
                    return hexHeader.startsWith("252150532D41"); // %!PS-Adobe（前6字节）
                case "psd":
                    return hexHeader.startsWith("38425053"); // 8BPS
                case "tga":
                    return hexHeader.startsWith("00000200") || hexHeader.startsWith("00001000"); // TGA两种签名
                // 以下类型无通用签名或较复杂，暂时通过后缀+基础验证
                case "pcp":
                case "dif":
                case "cdr":
                case "iff":
                case "pcd":
                case "mpt":
                    return read > 0;
                default:
                    return false;
            }
        } catch (IOException e) {
            log.error("读取文件头失败", e);
            return false;
        }
    }

    /**
     * 字节数组转十六进制字符串（大写）
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

    /**
     * 通过文件名后缀校验是否为图片
     *
     * @param extName
     * @return true:是图片文件
     */
    public static Boolean checkImageType(String extName) {
        if (StringUtils.isBlank(extName)) {
            log.info("上传的文件后缀名获取不到,拒绝上传");
            return false;
        }
        extName = extName.toLowerCase();
        if (IMAGE_TYPE.contains(extName)) {
            return true;
        } else {
            log.info("上传的文件后缀名不是支持的文件格式,拒绝上传");
            return false;
        }
    }
}
